﻿//-----------------------------------------------------------------------
// <copyright file="FCISPlusServerCommunicator.cs" company="FCIS">
//     Company copyright tag.
// </copyright>
// <author>Ramy Medhat</author>
// <date>24/8/2011</date>
// <reviewer></reviewer>
//-----------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FCISPlus.Server.Backend;
using FCISPlus.Server.Database;

namespace FCISPlus.Server.Communicator
{
    /// <summary>
    /// FCIS+ Server Communicator
    /// </summary>
    internal class FCISPlusServerCommunicator : IFCISPlusServerCommunicator
    {
        /// <summary>
        /// Sessions dictionary, accessible by tokens.
        /// </summary>
        private Dictionary<int, User> sessions;

        /// <summary>
        /// The FCIS+ server.
        /// </summary>
        private FCISPlusServer server;

        /// <summary>
        /// Initializes a new instance of the <see cref="FCISPlusServerCommunicator"/> class.
        /// </summary>
        public FCISPlusServerCommunicator()
        {
            this.sessions = new Dictionary<int, User>();
            this.server = new FCISPlusServer();
        }

        #region IFCISPlusServerCommunicator Members

        /// <summary>
        /// Logins the specified username.
        /// </summary>
        /// <param name="username">The username.</param>
        /// <param name="password">The password.</param>
        /// <returns>
        /// The session token.
        /// </returns>
        public int Login(string username, string password)
        {
            bool result = this.server.CheckLogin(username, password);

            if (result == false)
            {
                return -1;
            }
            else
            {
                Random randomGenerator = new Random();
                int random = randomGenerator.Next();

                while (this.sessions.Keys.Contains(random))
                {
                    random = randomGenerator.Next();
                }

                User user = this.server.GetUser(username);
                this.sessions.Add(random, user);

                return random;
            }
        }


        /// <summary>
        /// Gets all users.
        /// </summary>
        /// <returns>Array of users.</returns>
        public User[] GetAllUsers()
        {
            return server.GetAllUsers();
        }

        /// <summary>
        /// Gets the user.
        /// </summary>
        /// <param name="token">The token.</param>
        /// <returns>The user object.</returns>
        public User GetUser(int token)
        {
            return this.sessions[token];
        }

        /// <summary>
        /// Logouts using the specified token.
        /// </summary>
        /// <param name="token">The token.</param>
        public void Logout(int token)
        {
            this.sessions.Remove(token);
        }

        /// <summary>
        /// Adds the post.
        /// </summary>
        /// <param name="postText">The post text.</param>
        /// <param name="postLink">The post link.</param>
        /// <param name="token">The token.</param>
        public void AddPost(string postText, string postLink, int token)
        {
            this.server.AddPost(this.sessions[token], postText, postLink);
        }

        /// <summary>
        /// Deletes the post.
        /// </summary>
        /// <param name="post">The post.</param>
        /// <param name="token">The token.</param>
        public void DeletePost(Post post, int token)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Signs up.
        /// </summary>
        /// <param name="username">The username.</param>
        /// <param name="password">The password.</param>
        /// <returns>
        /// The session token.
        /// </returns>
        public int SignUp(string username, string password)
        {
            User user = this.server.CreateUser(username, password);

            if (user == null)
            {
                return -1;
            }

            return this.Login(username, password);
        }

        /// <summary>
        /// Gets the friends.
        /// </summary>
        /// <param name="token">The token.</param>
        /// <returns>
        /// .Array of friends
        /// </returns>
        public Database.User[] GetFriends(int token)
        {
            return this.server.GetFriends(this.sessions[token]);
        }

        /// <summary>
        /// Adds the friend.
        /// </summary>
        /// <param name="friend">The friend.</param>
        /// <param name="token">The token.</param>
        public void AddFriend(Database.User friend, int token)
        {
            this.server.AddFriendToUser(this.sessions[token], friend);
        }

        /// <summary>
        /// Removes the friend.
        /// </summary>
        /// <param name="friend">The friend.</param>
        /// <param name="token">The token.</param>
        public void RemoveFriend(Database.User friend, int token)
        {
            this.server.RemoveFriendFromUser(this.sessions[token], friend);
        }

        /// <summary>
        /// Gets the feeds.
        /// </summary>
        /// <param name="token">The token.</param>
        /// <returns>
        /// Array of posts.
        /// </returns>
        public Database.Post[] GetFeeds(int token)
        {
            return this.server.GetUserFeeds(this.sessions[token]);
        }

        /// <summary>
        /// Adds the comment.
        /// </summary>
        /// <param name="commentText">The comment text.</param>
        /// <param name="post">The post.</param>
        /// <param name="token">The token.</param>
        public void AddComment(string commentText, Database.Post post, int token)
        {
            this.server.AddComment(this.sessions[token], post, commentText);
        }

        /// <summary>
        /// Likes the specified post.
        /// </summary>
        /// <param name="post">The post.</param>
        /// <param name="token">The token.</param>
        public void Like(Database.Post post, int token)
        {
            this.server.Like(this.sessions[token], post);
        }

        /// <summary>
        /// Unlikes the specified post.
        /// </summary>
        /// <param name="post">The post.</param>
        /// <param name="token">The token.</param>
        public void Unlike(Database.Post post, int token)
        {
            this.server.Unlike(this.sessions[token], post);
        }

        /// <summary>
        /// Sends the message.
        /// </summary>
        /// <param name="friend">The friend.</param>
        /// <param name="messageText">The message text.</param>
        /// <param name="token">The token.</param>
        public void SendMessage(User friend, string messageText, int token)
        {
            this.server.SendMessage(this.sessions[token], friend, messageText);
        }

        /// <summary>
        /// Gets the recent conversations.
        /// </summary>
        /// <param name="user">The user.</param>
        /// <param name="messageLifeTime">The message life time.</param>
        /// <param name="token">The token.</param>
        /// <returns></returns>
        public Message[] GetRecentConversations(TimeSpan messageLifeTime, int token)
        {
            return this.server.GetRecentConversations(this.sessions[token], messageLifeTime);
        }

        /// <summary>
        /// Gets the conversation by friend.
        /// </summary>
        /// <param name="friend">The friend.</param>
        /// <param name="messageLifeTime">The message life time.</param>
        /// <param name="token">The token.</param>
        /// <returns></returns>
        public Message[] GetConversationByFriend(User friend, TimeSpan messageLifeTime,int token)
        {
            return this.server.GetConversationByFriend(this.sessions[token], friend, messageLifeTime);
        }
        #endregion
    }
}
